package cfsmon.logic.dfm;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import cfsmon.common.Event;
import cfsmon.common.Parameter;

public class Dfm implements IDfm {

	private int maximumNumberOfMonitors;
	
	private Map<String, DfmState> states;
	private Set<DfmState> finalStates;
	private DfmState initialState;
	
	private Map<String, Event> events;
	private Map<String, Parameter> parameters;
	
	public Dfm(){
		states = new HashMap<String, DfmState>();
		finalStates = new HashSet<DfmState>();
		initialState = null;
		
		events = new HashMap<String, Event>();
		parameters = new HashMap<String, Parameter>();
		maximumNumberOfMonitors = 1;
	}
	
	public Dfm(
			Map<String, DfmState> states,
			DfmState initialState,
			Set<DfmState> finalStates,
			Map<String, Event> events,
			Map<String, Parameter> parameters,
			int maximumNumberOfMonitors
			){
		this.states = states;
		this.finalStates = finalStates;
		this.initialState = initialState;
		this.events = events;
		this.parameters = parameters;
		this.maximumNumberOfMonitors = maximumNumberOfMonitors;
	}
	
	@Override
	public int getMaximumNumberOfMonitors() {
		return maximumNumberOfMonitors;
	}

	@Override
	public void setMaximumNumberOfMonitors(int max) {
		maximumNumberOfMonitors = max;
	}

	@Override
	public Map<String, DfmState> getStates() {
		return states;
	}

	@Override
	public void addState(DfmState state) {
		states.put(state.getName(), state);
	}

	@Override
	public Set<DfmState> getFinalStates() {
		return finalStates;
	}

	@Override
	public void addFinalState(DfmState state) {
		addState(state);
		finalStates.add(state);
	}

	@Override
	public DfmState getInitialState() {
		return initialState;
	}

	@Override
	public void setInitialState(DfmState state) {
		addState(state);
		initialState = state;
	}

	@Override
	public Map<String, Event> getEvents() {
		return events;
	}

	@Override
	public void addEvent(Event event) {
		events.put(event.name, event);
	}

	@Override
	public Map<String, Parameter> getParameters() {
		return parameters;
	}

	@Override
	public void addParameter(Parameter parameter) {
		parameters.put(parameter.name, parameter);
	}

	@Override
	public void print() {
		StringBuffer sb = new StringBuffer();
		sb.append("Parameters := " + parameters.values().toString() + "\r\n");
		sb.append("Max monitors := " + maximumNumberOfMonitors + "\r\n");
		sb.append("States := " + states.keySet().toString() + "\r\n");
		sb.append("Events := " + events.values().toString() + "\r\n");
		sb.append("Initial state := " + initialState + "\r\n");
		sb.append("Final states := " + finalStates.toString() + "\r\n");
		System.out.println(sb.toString());
		
		// print out transitions
		System.out.println("Transitions := delta : States x Events -> States");
		for (DfmState s : states.values()){
			s.printDeep();
		}
	}

}
